<template>
  <div class="component-upload-image">
    <div v-if="limit > 1">
      <vuedraggable tag="ul" v-model="fileList" v-bind="dragOptions" draggable=".draggable-item" class="flexBox"
                    :move="onMove" @end="endMove">
        <!-- 拖拽元素 -->
        <li v-for="(item, index) in fileList" :key="item.name + index" class="draggable-item"
            :class="index==chooseImgValue? 'chooseStyle':'' " @mouseenter="showDelBtn(index,item)"
            @mouseleave="hiddenDelBtn">
          <el-image style="width: 148px; height: 148px" fit="cover" :src="item.url" :ref="'imgSize' + index"
                    :preview-src-list="[item.url]" @load="imgload(index)">
          </el-image>
          <div v-if="isShowImgFormat">此图片格式为：{{ item.imgFormat }}</div>
          <div v-if="isShowNonStandardImgTip && item.nonStandardImg" class="text-danger">
            图片格式需调整
          </div>
          <div v-if="isShowRecommend && !isShowrecommendScale">推荐尺寸：{{ recommendSize }}</div>
          <div v-if="isShowrecommendScale && isShowRecommend">推荐比例：{{ recommendScale }}</div>
          <span :class="{isError:item.isTrue&&isShowRecommend}"
                v-if="isShowSize && isLoadedImg ">实际尺寸：{{ item.imageWidth }}*{{ item.imageHeight }}</span>
          <div v-if="isShowChooseImg" class="changeHand text-blue mt10" @click="chooseImg(item,index)">选择图片</div>
          <div v-if="isShowCreateImg" class="changeHand text-blue mt10" @click="chooseCreateImg(item,index)">
            生成白底图
          </div>
          <div>
            <el-button v-if="isAi" type="text" :loading="systemLoadIndex === index" :disabled="systemLoding"
                       @click="systemDrawing(item, index)" size="mini">
              AI制图
            </el-button>
            <el-button v-if="isEdit" type="text" @click="$emit('picture-edit', item, index)" size="mini">
              图片优化
            </el-button>
          </div>
          <div class="maskbox" v-if="!aiLoading" @click="deleImg(item, index)">
            <i v-show="index == currentDelBtn" class="el-icon-delete delIcon"/>
          </div>
        </li>
        <!-- 上传按钮 -->
        <el-upload action="" ref='imageUpload' multiple list-type="picture-card" :limit="limit"
                   :show-file-list="false" :file-list="fileList" :on-success="handleUploadSuccess"
                   :on-error="handleUploadError" :on-exceed="handleExceed" :before-upload="handleBeforeUpload"
                   :headers="headers" :class="{hide: this.fileList.length >= this.limit,changeSize:this.changeSize}"
                   :http-request="handleUpload">
          <i class="el-icon-plus"></i>
        </el-upload>
      </vuedraggable>
    </div>
    <div v-else>
      <el-upload action="" multiple :http-request="handleUpload" list-type="picture-card"
                 :on-success="handleUploadSuccess" :before-upload="handleBeforeUpload" :limit="limit"
                 :on-error="handleUploadError" :on-exceed="handleExceed" ref="imageUpload" :on-remove="handleDelete"
                 :show-file-list="true" :headers="headers" :file-list="fileList" :disabled="isDisabled"
                 :on-preview="handlePictureCardPreview" :before-remove="beforeRemove" :atlasType="atlasType"
                 :class="{hide: this.fileList.length >= this.limit,changeSize:this.changeSize}">
        <i class="el-icon-plus"></i>
      </el-upload>
      <div v-if="isShowRecommend">推荐尺寸：{{ recommendSize }}</div>
      <!--      <div v-if="isShowRecommend && atlasType == 3 ">推荐比例：{{ recommendScale }}</div>-->
      <div :class="{isError: this.isTrue && isShowRecommend}" v-if="fileList.length > 0 && isShowSize">
        实际尺寸：{{ imgPx }}{{ imgWH }}
      </div>
      <el-button v-if="isAi" type="text" :loading="systemLoding" :disabled="systemLoding" @click="systemImage(fileList)"
                 size="mini">
        AI制图
      </el-button>
      <el-button v-if="isEdit" type="text" @click="$emit('picture-edit')" size="mini">
        图片优化
      </el-button>
    </div>
    <!-- 上传提示 -->
    <div class="el-upload__tip" slot="tip" v-if="showTip">
      请上传
      <template v-if="fileSize">大小不超过<b style="color: #f56c6c">{{ fileSize }}MB</b></template>
      <template v-if="isLimitsize">尺寸为
        <b style="color: #f56c6c">{{ atlasType == 3 ? '800*800' : atlasType == 0 ? '1:1' : ' 750*1000' }}</b>
      </template>
      <template v-if="fileType">格式为<b style="color: #f56c6c">{{ fileType.join("/") }}</b></template>
      的文件
    </div>
    <el-dialog :visible.sync="dialogVisible" title="预览" append-to-body>
      <el-image :src="dialogImageUrl" fit="cover" width="150px" height="150px">
        <div slot="error" class="image-slot">
          <i class="el-icon-picture-outline"></i>
        </div>
      </el-image>
    </el-dialog>
  </div>
</template>

<script>
import store from '@/store'
import {
  getToken
} from "@/utils/auth";
import vuedraggable from 'vuedraggable';
import {
  bucketUpload
} from "@/utils/alioss";
import {aiDesign, sysImageMerge} from '@/api/seller/sellerProduct';
import {isError} from "vue-router/src/util/errors";

export default {
  components: {vuedraggable},
  props: {
    value: [String, Array],
    isShowImgFormat: { //是否显示图片格式
      type: Boolean,
      default: false
    },
    isShowNonStandardImgTip: { //是否显示不规范图片提示
      type: Boolean,
      default: false
    },
    isShowChooseImg: { //是否显示选择图片
      type: Boolean,
      default: false
    },
    isShowCreateImg: {//是否显示生成白底或营销图
      type: Boolean,
      default: false
    },
    isGet: {
      type: Boolean
    },
    tabIndex: {
      type: Number / String
    },
    // 图片数量限制
    limit: {
      type: Number,
    },
    // 是否显示图片尺寸
    isShowSize: {
      type: Boolean,
      default: false,
    },
    isDisabled: { //是否禁用
      type: Boolean,
      default: false
    },
    // 修改上传图片图标的尺寸
    changeSize: {
      type: Boolean,
      default: false
    },
    // 大小限制(MB)
    fileSize: {
      type: Number,
      default: 10,
    },
    // 文件类型, 例如['png', 'jpg', 'jpeg']
    fileType: {
      type: Array,
      default: () => ["png", "jpg", "jpeg"],
    },
    // 是否显示提示
    isShowTip: {
      type: Boolean,
      default: true
    },
    // 是否显示提示
    isLimitsize: {
      type: Boolean,
      default: false
    },
    //  图集类型 0,轮播图，1.详情图，2.营销图，3.白底图
    atlasType: {
      type: String / Number,
      default: ""
    },
    // 是否显示AI制图
    isAi: {
      type: Boolean,
      default: false
    },
    // 商品id
    productId: {
      type: String,
      default: ''
    },
    // 图片优化
    isEdit: {
      type: Boolean,
      default: false
    },
    // 推荐尺寸
    recommendSize: {
      type: String,
      default: "800*800"
    },
    // 推荐比例
    isShowrecommendScale: {
      type: Boolean,
      default: false
    },
    // 是否显示推荐尺寸
    isShowRecommend: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      number: 0,
      uploadList: [],
      dialogImageUrl: "",
      dialogVisible: false,
      hideUpload: false,
      baseUrl: process.env.VUE_APP_BASE_API,
      uploadImgUrl: process.env.VUE_APP_BASE_API + "/system/oss/upload", // 上传的图片服务器地址
      headers: {
        Authorization: "Bearer " + getToken(),
      },
      currentDelBtn: -1,
      aiLoading: false,//AI制图loading
      systemLoding: false,//系统制图loading
      aiLoadIndex: '',
      systemLoadIndex: "",//系统制图下标
      imgInfo: "",
      imgSize: '',
      isLoadedImg: false,
      imgWH: '',
      isTrue: false,
      recommendScale: "1:1",
      chooseImgValue: undefined,// 选择图片下标
      chooseImgStyle: {}
    };
  },
  created() {
  },
  computed: {
    fileList: {
      get() {
        const val = this.value
        if (val) {
          // 首先将值转为数组
          // const list = Array.isArray(val) ? val : (this.value || '').split(',').filter(item => !!item);
          const list = Array.isArray(val) ? val : (this.value || '').split(';').filter(item => !!item);
          // console.log('list', list)
          // 然后将数组转为对象数组
          return list.map(item => {
            // console.log('item', typeof item, item)
            if (typeof item === "string") {
              if (item.indexOf('http://') === -1 && item.indexOf('https://') === -1) {
                item = {
                  name: item,
                  url: store.getters.domain + item,
                };
              } else {
                item = {
                  name: item,
                  url: item
                };
              }
            } else if (item.atlasId) {
              item = {
                name: item.atlasId,
                url: store.getters.domain + item.pictureUrl,
              };
            } else {
              item = {
                name: item.name,
                url: item.url,
              }
            }
            return item;
          });
        } else {
          return [];
        }
      },
      set(val) {
        this.$emit('input', val.map(item => item.name).join(';'))
      }
    },
    // 是否显示提示
    showTip() {
      return this.isShowTip && (this.fileType || this.fileSize);
    },
    dragOptions() {
      return {
        animation: 200,
        group: "description",
        disabled: false,
        ghostClass: "ghost"
      };
    },
    imgPx() {
      if (this.fileList.length > 0) {
        this.getImgPx(this.fileList[0].url)
      } else return ''
    }
  },
  methods: {
    isError,
    // 单张图片大小
    getImgPx(url) {
      const image = new Image()
      image.src = url
      new Promise((resolve) => {
        image.onload = () => {
          const width = image.width
          const height = image.height
          const recommendSize = this.recommendSize.split('*')
          // console.log('recommendSize', recommendSize)
          if (Number(recommendSize[0]) === Number(width) && Number(recommendSize[1]) === Number(height)) {
            this.isTrue = false;
          } else {
            this.isTrue = true;
          }
          resolve(width + '*' + height)
        }
      }).then(res => {
        this.imgWH = res
      })
    },
    onMove(e, originalEvent) {
      // console.log('被拖拽对象的信息', e.draggedContext.element)
      // console.log('将停靠对象的信息', e.relatedContext.element)
    },
    // 拖拽完成事件
    endMove(e) {
      // console.log('e拖拽完成', e.item._underlying_vm_)
      // console.log(' this.$refs.imgSize', this.$refs.imgSize)
      let data = e.item._underlying_vm_;
      this.isLoadedImg = false

      setTimeout(() => {
        // console.log('****')
        this.isLoadedImg = true
      }, 1000)
    },
    imgload(index) {
      if (this.$refs['imgSize' + index]) {
        this.isLoadedImg = false
        // let imgSize = this.$refs['imgSize' + index][0]
        const recommendSize = this.recommendSize.split('*')
        // console.log('recommendSize', recommendSize)
        let imgList = [];
        for (let j = 0; j < this.fileList.length; j++) {
          let imgSize = this.$refs['imgSize' + j][0]
          let imgWidth = imgSize.imageWidth
          let imgHeight = imgSize.imageHeight
          let imgFormat = imgSize.src.slice(-3)
          if (this.isShowrecommendScale) { //如果是显示比例的图片

            // 1、图片的宽度等于高度。2、图片的宽度或高度必须大于800
            // if (Number(imgWidth) == Number(imgHeight) || (Number(recommendSize[0]) <= Number(imgWidth) && Number(recommendSize[1]) <= Number(imgHeight))) {
            // }
            if ((Number(recommendSize[0]) === Number(imgWidth) && Number(recommendSize[1]) === Number(imgHeight)) || (Number(recommendSize[0]) <= Number(imgWidth) && Number(recommendSize[1]) <= Number(imgHeight))) {
              this.$set(this.fileList[j], 'isTrue', false);
            } else {
              this.$set(this.fileList[j], 'isTrue', true);
            }
          } else {
            if (Number(recommendSize[0]) === Number(imgWidth) && Number(recommendSize[1]) === Number(imgHeight)) {
              this.$set(this.fileList[j], 'isTrue', false);
            } else {
              this.$set(this.fileList[j], 'isTrue', true);
            }
          }
          // console.log('imgSize', imgSize.src)
          if (imgSize.src.indexOf('ae01.ali') == -1 && imgSize.src.indexOf('common-product') == -1) {
            // console.log('@@@@@@@@@@2', imgSize.src)
            let nonStandardImg = imgSize.src
            imgList.push(nonStandardImg)
            this.$set(this.fileList[j], 'nonStandardImg', nonStandardImg);
          }
          this.$set(this.fileList[j], 'imageHeight', imgHeight);
          this.$set(this.fileList[j], 'imageWidth', imgWidth);
          this.$set(this.fileList[j], 'imgFormat', imgFormat);
        }
        this.isLoadedImg = true
        this.$emit('getNonStandardImg', imgList)
      }
    },
    // ai制图
    aiDesignBtn(item, index) {
      const params = {
        productId: this.productId,
        url: item.name
      }
      const loading = this.$loading({
        lock: true,
        text: '制图中，请稍等',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      });
      this.aiLoadIndex = index;
      this.aiLoading = true;
      aiDesign(params).then(res => {
        this.aiLoading = false;
        this.aiLoadIndex = '';
        loading.close();

        if (res.code === 200) {
          var arr = [...this.fileList]
          this.$modal.msgSuccess(res.msg);
          arr[index].name = res.data;
          arr[index].url = store.getters.domain + res.data;
          this.fileList = arr;
        }
      }).catch((e) => {
        this.aiLoadIndex = '';
        loading.close();
        this.aiLoading = false;
      });
    },
    // 系统制图
    systemImage(url) {
      const params = {
        productId: this.productId,
        imgUrl: url[0].name
      }
      const loading = this.$loading({
        lock: true,
        text: '制图中，请稍等',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      });
      this.systemLoding = true;
      sysImageMerge(params).then(res => {
        this.systemLoding = false;
        loading.close();
        if (res.code === 200) {
          var arr = [...this.fileList]
          this.$modal.msgSuccess(res.msg);
          arr[0].name = res.data;
          arr[0].url = store.getters.domain + res.data;
          this.fileList = arr;
        }
      }).catch((e) => {
        this.systemLoding = false;
        loading.close();
      });
    },
    // 系统制图
    systemDrawing(item, index) {
      const params = {
        productId: this.productId,
        imgUrl: item.name
      }
      this.systemLoadIndex = index;
      const loading = this.$loading({
        lock: true,
        text: '制图中，请稍等',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      });
      this.systemLoding = true;
      sysImageMerge(params).then(res => {
        this.systemLoding = false;
        loading.close();
        this.systemLoadIndex = '';
        if (res.code === 200) {
          var arr = [...this.fileList]
          this.$modal.msgSuccess(res.msg);
          arr[index].name = res.data;
          arr[index].url = store.getters.domain + res.data;
          this.fileList = arr;
        }
      }).catch((e) => {
        this.systemLoadIndex = '';
        this.systemLoding = false;
        loading.close();
      });
    },
    // 上传
    handleUpload(op) {
      console.log('op', op)
      let bucketName = '' // 桶名
      let dir = `images`
      bucketUpload(
        op.file,
        res => {
          console.log('resssss', res)
          let temp = {
            name: res.attachment,
            url: res.aliyunAddress,
            code: res.code
          }
          // this.host = res.host
          op.onSuccess(temp)
        },
        err => {
        },
        bucketName,
        dir
      )
    },
    // 上传前loading加载
    async handleBeforeUpload(file) {
      console.log('111111111111')
      let isImg = false;
      if (this.fileType.length) {
        let fileExtension = "";
        if (file.name.lastIndexOf(".") > -1) {
          fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
        }
        isImg = this.fileType.some(type => {
          if (file.type.indexOf(type) > -1) return true;
          if (fileExtension && fileExtension.indexOf(type) > -1) return true;
          return false;
        });
      } else {
        isImg = file.type.indexOf("image") > -1;
      }

      if (!isImg) {
        this.$modal.msgError(`文件格式不正确, 请上传${this.fileType.join("/")}图片格式文件!`);
        return false;
      }
      if (this.fileSize) {
        const isLt = file.size / 1024 / 1024 < this.fileSize;
        if (!isLt) {
          this.$modal.msgError(`上传头像图片大小不能超过 ${this.fileSize} MB!`);
          return false;
        }
      }

      if (this.atlasType) {
        // if (false) {
        const result = await this.checkImg(file);    //若没有上传图片不通过， 就直接跳出
        // console.log('result', result)
        if (!result) return;
      } else {
        this.$emit("beforeUpload", file);
      }
      this.$modal.loading("正在上传图片，请稍候...");
      this.number++;
    },
    // 图片尺寸校验
    checkImg(file) {
      const isSize = new Promise((resolve, reject) => {
        const _URL = window.URL || window.webkitURL;
        let img = new Image();
        img.onload = () => {
          var valid = "";
          // console.log('this.atlasType', this.atlasType, img.width, img.height)
          // if (this.atlasType) {
          if (this.atlasType == '0') {//轮播图
            valid = (img.width / img.height) === 1;
          } else if (this.atlasType == '3') {//白底图
            valid = img.width === 800 && img.height === 800;
          } else if (this.atlasType == '2' || this.atlasType == '1') {//营销图
            valid = img.width === 750 && img.height === 1000;
          }
          valid ? resolve() : reject();
          // }
          // console.log('valid11', valid, resolve(), reject())
        };
        img.src = _URL.createObjectURL(file);
      }).then(() => {
          this.$emit("beforeUpload", file);
          return file;
        }, () => {
          var message = "";
          if (this.atlasType == '0') {
            message = "图片尺寸大小必须为1:1"
          } else if (this.atlasType == '3') {
            message = "图片尺寸大小必须为800*800"
          } else if (this.atlasType == '2' || this.atlasType == '1') {
            message = "图片尺寸大小必须为750*1000"
          }
          this.$modal.msgError(message);   //  我这里是将upload组件进一步封装了， imgW, imgH是图片限制的条件参数
          return Promise.reject(false);
        }
      );
      console.log('isSize', isSize)
      return isSize;
    },
    // 文件个数超出
    handleExceed() {
      this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);
    },
    // 上传成功回调
    handleUploadSuccess(res, file) {
      if (res.code === 200) {
        this.uploadList.push({
          name: res.name,
          url: res.url
        });
        this.uploadedSuccessfully();
      } else {
        this.number--;
        this.$modal.closeLoading();
        this.$modal.msgError(res.msg);
        this.$refs.imageUpload.handleRemove(file);
        this.uploadedSuccessfully();
      }
    },
    // 删除图片前的确认
    beforeRemove(file) {
      const isDelete = new Promise((resolve, reject) => {
        if (file.size) {
          resolve(true)
        } else {
          this.$confirm('是否确认删除该图片？', "提示", {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {
            resolve(true)
          }).catch(() => {
            reject(false)
          })
        }
      })
      return isDelete
    },
    // 删除图片
    handleDelete(file) {
      this.$emit("deleteImg", file)
      const findex = this.fileList.map(f => f.name).indexOf(file.name);
      console.log('findex', findex)
      if (findex > -1) {
        const ls = [...this.fileList]
        ls.splice(findex, 1);
        this.fileList = ls
        // this.imgload()
      }

    },
    // 上传失败
    handleUploadError() {
      this.$modal.msgError("上传图片失败，请重试");
      this.number--;
      this.$modal.closeLoading();
    },
    // 上传结束处理
    uploadedSuccessfully() {
      if (this.number > 0 && this.uploadList.length === this.number) {
        this.fileList = this.fileList.concat(this.uploadList);
        this.uploadList = [];
        this.number = 0;
        this.$modal.closeLoading();
      }
    },
    // 预览
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url;
      this.dialogVisible = true;
    },
    // 对象转成指定字符串分隔
    listToString(list, separator) {
      let strs = "";
      separator = separator || ",";
      for (let i in list) {
        if (list[i].url) {
          strs += list[i].url.replace(this.baseUrl, "") + separator;
        }
      }
      return strs != '' ? strs.substr(0, strs.length - 1) : '';
    },
    // 显示删除图片的图标
    showDelBtn(index, item) {
      // console.log('index', index, item)
      this.imgload()
      this.currentDelBtn = index
    },
    // 隐藏删除图片的图标
    hiddenDelBtn() {
      this.currentDelBtn = -1
    },
    // 删除图片
    deleImg(file) {
      // this.$confirm("是否确定要删除该图片？", "提示").then(() => {
      const findex = this.fileList.map(f => f.name).indexOf(file.name);
      // console.log('findex', findex)
      if (findex > -1) {
        const ls = [...this.fileList]
        ls.splice(findex, 1);
        this.fileList = ls
        this.$emit("deleteImg", file, ls, this.atlasType)
        this.$modal.msgSuccess("删除成功");
      } else {
        this.$modal.msgSuccess("删除失败，请联系管理员！");
      }
      // })
    },
    // 选择图片
    chooseImg(item, index) {
      this.chooseImgValue = index
      // console.log('item', item)
      this.$emit('getChooseImg', item.url)
    },
    // 选择生成白底或营销
    chooseCreateImg(item, index) {
      this.chooseImgValue = index
      // console.log('item', item)
      this.$emit('getChooseCreateImg', item.url)
    },
  }
};
</script>
<style scoped lang="scss">
.el-image {
  border-radius: 5px;
  background-color: rgba(175, 174, 174, 0.45);
  box-shadow: 0 0 5px 1px #ccc;

  ::v-deep .el-image__inner {
    transition: all 0.3s;
    cursor: pointer;

    &:hover {
      transform: scale(1.2);
    }
  }

  ::v-deep .image-slot {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
    height: 100%;
    color: #909399;
    font-size: 30px;
  }
}

ul,
li {
  padding: 0;
  margin: 0;
  list-style: none
}

.flexBox {
  display: flex;
  flex-wrap: wrap;

  .chooseStyle {
    background-color: #dddddd;
    border-radius: 10px;
  }

  .draggable-item {
    position: relative;
    margin-right: 10px;
    margin-bottom: 10px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 10px;

    .maskbox {
      position: absolute;
      right: 10px;
      top: 5px;
      width: 30px;
      height: 30px;
      text-align: center;
      //transform: rotate(45deg);
      background-color: rgba(245, 108, 108);
      color: #ffffff;
      font-size: 24px;
      opacity: 0;
      transition: opacity 0.3s;
    }

    &:hover .maskbox {
      opacity: 1;
    }

    .el-image {
      border-radius: 6px;
      border: 1px solid #c0ccda;
    }
  }
}

// .el-upload--picture-card 控制加号部分
::v-deep.hide .el-upload--picture-card {
  display: none;
}

// 去掉动画效果
::v-deep .el-list-enter-active,
::v-deep .el-list-leave-active {
  transition: all 0s;
}

::v-deep .el-list-enter,
.el-list-leave-active {
  opacity: 0;
  transform: translateY(0);
}

::v-deep .changeSize .el-upload--picture-card {
  width: 70px;
  height: 70px;
  line-height: 70px;
}

::v-deep .changeSize .el-upload-list--picture-card .el-upload-list__item {
  width: 70px;
  height: 70px;
  // line-height: 70px;
}

::v-deep .el-upload-list__item {
  margin: 0;
}

.isError {
  color: #F56C6C;
}
</style>
